package org.i0o.webplus.commons.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 泛型操作的工具类,通过反射获得Class声明的范型Class.
 * 
 * @author <a href="mailto:781131@gmail.com">HTF</a>
 */
public final class GenericsUtils {

	private GenericsUtils() {
	}

	/**
	 * 返回表示此 Class 所申明的第一个泛型
	 * 
	 * @param clazz 类
	 * @return 第一个泛型，如果不是泛型 返回Object.Class
	 */
	public static Class<?> getGenericClass(Class<?> clazz) {
		return getGenericClass(clazz, 0);
	}

	/**
	 * 按序号返回表示此 Class 所申明的泛型
	 * 
	 * @param clazz 类
	 * @param index 序号，从0开始
	 * @return 指定的泛型，如果不是泛型 返回Object.Class
	 * @throws IndexOutOfBoundsException
	 */
	public static Class<?> getGenericClass(Class<?> clazz, int index) throws IndexOutOfBoundsException {

		Type genType = clazz.getGenericSuperclass();
		while (!(genType instanceof ParameterizedType)) {
			if (clazz == Object.class) {
				return Object.class;
			}
			clazz = clazz.getSuperclass();
			genType = clazz.getGenericSuperclass();
		}

		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		if (index >= params.length || index < 0) {
			throw new IndexOutOfBoundsException("Index: " + index + ", Size of Parameterized Type: " + params.length);
		}
		return (Class<?>) params[index];
	}
}
